var formidable = require('formidable'),
	url = require("url"), 
	appUtil = require('./util'), 
	path = require("path"), 
	fs = require("fs"), 
	ViewEngine = require('./view').ViewEngine,
	config = require('../config'),
	contentTypes = require('./contentTypes'),
	route = require('./route');

/**
 * 处理静态文件
 * @param req
 * @param res
 * @param filePath
 * @returns
 */
exports.handleStaticFile = function(req, res, filePath){
	if (!filePath) {
		filePath = path.join(config.baseDir, config.staticFileDir, url.parse(req.url).pathname);
	}
	path.exists(filePath, function(exists) {
		if (!exists) {
			handler404(res);
			return;
		}

		fs.readFile(filePath, "binary", function(err, file) {
			if (err) {
				handler500(res, err);
				return;
			}

			var ext = path.extname(filePath);
			ext = ext || '.html';
			res.writeHead(200, {
				'Content-Type' : contentTypes.contentTypes[ext] || 'text/html'
			});
			res.write(file, "binary");
			res.end();
		});
	});
}

/**
 * 处理html文件
 * @param req
 * @param res
 * @param filePath
 * @returns
 */
exports.handleHtmlFile = function(req, res, webForm){
	exports.handleStaticFile(req, res, webForm.getActionPath());
}

/**
 * 处理动态文件
 * @param req
 * @param res
 * @param filePath
 * @returns
 */
exports.handleDynamicFile = function(req, res, webForm){
	var method = req.method ? req.method.toLowerCase() : 'get';

	//动态请求处理
	if(req.method.toUpperCase()=='GET'){//处理get请求
		webForm.setReq(req);
		webForm.setMethod(method);
		var retStr = invokeAction(req, res, webForm);
		send(res, webForm, retStr);
		return;
	}else if(req.method.toUpperCase()=='POST'){//处理post请求
		var form = new formidable.IncomingForm(), files = [], fields = [];
		var fields = {};
		var files = {};
		form.on('field', function(field, value) {
			console.log(field+":"+value);
			fields[field] = value;
		}).on('file', function(field, file) {
			files[field] = file;
		}).on('error', function(error){
			console.log(error);
			handler500(res, "服务器发生错误，请稍候再试！");
		}).on('end', function() {
			webForm.setReq(req);
			webForm.setMethod(method);
			console.log(fields);
			webForm.addAllParam(fields);
			webForm.setFiles(files);
			var retStr = invokeAction(req, res, webForm);
			send(res, webForm, retStr);
		});
		form.parse(req);
	}else if(req.method.toUpperCase()=='HEAD'){
		res.end(null);
		return;
	}
}

function invokeAction(req, res, webForm){
	var url = webForm.getUrl();
	var suffix = path.extname(url);
	var viewPath = webForm.getViewPath();
	var controllerPath = webForm.getAppPath() + "/"
			+ webForm.getControllerName();
	var action = require("../" + controllerPath);
	try {
		var actionName = webForm.getActionName();
		var fn = action[actionName];
		var ret = fn(webForm)||{};
		ret['session'] = webForm.getSession().getData();
		if(typeof(ret)=='string'){
			var _arr = ret.split(':');
			if(_arr.length!=2){
				console.log('action的返回格式不正确！');
				return null;
			}else{
				var t = _arr[0];
				if(t=='_r'){
					redirect(req, res, ret['_r']);
					return;
				}
				if(t=='_f'){
					forward(req, res, ret['_f'], webForm);
					return;
				}
			}
		}
		var viewEngine = new ViewEngine(config.templateType);
		return viewEngine.render(viewPath, webForm.getData(), res);
	} catch (e) {
		console.log("发生错误，文件：" + e.fileName + "，行号：" + e.lineNumber
				+ "，错误类型：" + e.name + "错误信息：" + e.message);
		if (e.name == "TypeError") {
			handleHtmlFile(res, config.err404Page);
		} else {
			handler500(res, "服务器发生错误，请稍候再试！");
		}
	}
}

/**
 * 客户端重定向
 * @param req
 * @param res
 * @param url
 * @returns
 */
var redirect = function(req, res, url){
	var base = config.basePath
	    , head = 'HEAD' == req.method
	    , status = 302
	    , body;
	if (!~url.indexOf('://')) {
	    if ('/' != base && 0 != url.indexOf(base)) url = base + url;
	    var host = req.headers.host
	      , tls = req.secure;
	    url = 'http' + (tls ? 's' : '') + '://' + host + url;
	}
	if (req.accepts('html')) {
	    body = '<p>' + statusCodes[status] + '. Redirecting to <a href="' + url + '">' + url + '</a></p>';
	    res.header('Content-Type', 'text/html');
	} else {
	    body = statusCodes[status] + '. Redirecting to ' + url;
	    res.header('Content-Type', 'text/plain');
	}

	// Respond
	res.statusCode = status;
	res.header('Location', url);
	res.end(head ? null : body);
};

/**
 * 服务端重定向
 * @param req
 * @param res
 * @param url
 * @returns
 */
var forward = function(req, res, newUrl, oldWebForm){
	var webForm = route.getWebForm(newUrl);
	if(webForm){
		webForm.setMethod(oldWebForm.getMethod());
		webForm.addAllParam(oldWebForm.getParams());
		webForm.setFiles(oldWebForm.getFiles());
		webForm.setSeq(seq);
		invokeAction(req, res, webForm);
	}else{
		handler404(res);
	}
};

var handler404 = function(res) {
	res.writeHead(404, {
		'Content-Type' : 'text/plain'
	});
	res.end('Page Not Found');
};

var handler500 = function(res, err) {
	res.writeHead(500, {
		'Content-Type' : 'text/plain'
	});
	res.end(err);
};


var handlerError = function(error, res){
	var viewPath = config.errorFile;
	var viewEngine = new ViewEngine(config.templateType);
	viewEngine.render(viewPath, error, res);
}

var send = function(res, webForm, retStr){
	var cookies = webForm.getResCookies();
	var setCookies = [];
	for(var i=0;i<cookies.length;i++){
		setCookies[setCookies.length] = ['Set-Cookie', cookies[i]];
	}
	res.writeHead(200,setCookies);
	res.end(retStr, "utf8");
}
